%{
#include <iostream>
#include <stdlib.h>
#include <string>
#include "absyn.h"
using namespace std;

extern "C"
{
    void yyerror(const char *s);
    extern int yylex(void);
    extern int line_no;

}
extern TreeNode savedTree;
extern vector<string> errMsg;
%}

%union
{
    int ival;
	double dval;
    char* sval;
	TreeNode node;
}


%token T_PROGRAM T_CONST T_TYPE T_VAR
%token T_FUNCTION T_PROCEDURE
%token <ival> T_INT
%token <dval> T_REAL
%token <sval> T_ID T_CHAR T_STRING
%token T_BEGIN T_END
%token T_TRUE T_FALSE 
%token T_READ T_WRITE 
%token T_IF T_THEN T_ELSE T_REPEAT T_UNTIL T_WHILE T_DO T_CASE T_TO T_DOWNTO T_FOR
%token T_EQUAL T_UNEQUAL T_GE T_GT T_LE T_LT T_ASSIGN T_PLUS T_MINUS T_MUL T_DIV T_OR T_AND T_NOT T_MOD
%token T_LB T_RB T_LP T_RP T_SEMI T_DOT T_DOTDOT T_COMMA T_COLON
%token T_INTEGER_TYPE T_BOOLEAN_TYPE T_CHAR_TYPE T_REAL_TYPE T_STRING_TYPE
%token T_ARRAY T_OF T_RECORD 
%token ERROR

%type <node> program program_head program_body identifier_list
%type <node> const_declarations type_declarations var_declarations subprogram_declarations compound_statement 
%type <node> const_declaration const_variable type_declaration type standard_type record_body periods var_declaration period subprogram_declaration subprogram_head formal_parameter parameter_lists parameter_list var_parameter value_parameter const_expr type_definition
%type <node> statement_list statement variable expression call_procedure_statement else_part case_body record_type array_type field_decl function_head procedure_head 
%type <node> id_varparts id_varpart expression_list branch_list branch const_list simple_expression ID  assign_statement if_statement case_statement while_statement repeat_statement for_statement 
%type <node> term factor
%type <node> unsign_const_variable


%%
program                 :   program_head program_body T_DOT
                            {   
                                $$=new TreeDefine(PROGRAM,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                                savedTree=$$;
                            };
                        |   program_head program_body
                                                    {   
                                $$=new TreeDefine(PROGRAM,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                                savedTree=$$;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of end dot");
                            };

program_head            :   T_PROGRAM T_ID T_LP identifier_list T_RP T_SEMI
                            {
                                $$=new TreeDefine(PROGRAMHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($4);
                            };
                        |   T_PROGRAM T_ID T_LP identifier_list T_RP 
                            {
                                $$=new TreeDefine(PROGRAMHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($4);
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };
                        

program_body            :   const_declarations type_declarations var_declarations subprogram_declarations compound_statement
                            {
                                $$=new TreeDefine(PROGRAMBODY,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                                $$->addChild($3);
                                $$->addChild($4);
                                $$->addChild($5);
                            };
identifier_list         :   identifier_list T_COMMA ID
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($3);
                                }
                                else
                                    $$=$3;
                            }
		                |   ID
                            {
                                $$=$1;
                            };
                        |   identifier_list ID
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($2);
                                }
                                else
                                    $$=$2;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of comma");
                                
                            };

const_declarations      :   {$$=NULL;}
		                |   T_CONST const_declaration T_SEMI
                            {
                                $$=$2;
                            };
                        |   T_CONST const_declaration 
                            {
                                $$=$2;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };


const_declaration       :   const_declaration T_SEMI const_expr 
                            {
                                TreeNode t = $1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                                $$=$3;
                            }
		                |   const_expr  {$$=$1;};
                        |   const_declaration const_expr 
                            {
                                TreeNode t = $1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };

const_expr              :ID T_EQUAL const_variable
                        {
                            $$=new TreeDefine(DK_CONST,line_no);
                            $$->setAttribute($1->getAttribute());
                            $$->addChild($3);
                            $$->setExpType($3->getExpType());
                        };
ID                  :   T_ID
                        {   $$=new TreeDefine(EK_ID,line_no);
                            $$->setAttribute($1);
                        } ;
const_variable          :   T_PLUS ID
                        {
                            $$=$2;
                        }
		                |   T_MINUS ID
                        {
                            $$=new TreeDefine($2, NULL, MINUS, line_no);
                            
                        }
		                |   ID
                        {
                            $$=$1;
                        }
		                |   T_PLUS T_INT
                        {   
                            $$ =new TreeDefine(EK_CONST,line_no);
                            $$->setExpType(INT);
                            $$->setAttribute($2);
                        }
		                |   T_MINUS T_INT
                        {   
                            TreeNode t=new TreeDefine(EK_CONST,line_no);
                            t->setExpType(INT);
                            t->setAttribute($2);
                            $$=new TreeDefine(t, NULL, MINUS, line_no);
                        }
                        |   T_PLUS T_REAL
                        {
                            $$ = new TreeDefine(EK_CONST,line_no);
                            $$->setExpType(REAL);
                            $$->setAttribute($2);
                        }
                        |   T_MINUS T_REAL
                        {
                            TreeNode t=new TreeDefine(EK_CONST,line_no);
                            t->setExpType(REAL);
                            t->setAttribute($2);
                            $$=new TreeDefine(t, NULL, MINUS, line_no);
                        }
		                |   T_INT
                        {
                            $$ =new TreeDefine(EK_CONST,line_no);
                            $$->setExpType(INT);
                            $$->setAttribute($1);
                        }
                        |   T_REAL
                        {
                            $$ = new TreeDefine(EK_CONST,line_no);
                            $$->setExpType(REAL);
                            $$->setAttribute($1);
                        };

type_declarations       :   {$$=NULL;}
		                |   T_TYPE type_declaration T_SEMI {$$=$2;};

type_declaration        :   type_declaration T_SEMI type_definition
                        {
                            TreeNode t=$1;
                            if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                              $$=$3;
                        }
                        |   type_declaration type_definition
                        {
                            TreeNode t=$1;
                            if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                              $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");
                        }
		                |   type_definition {$$=$1;};

type_definition         :   ID T_EQUAL type
                        {
                            $$=new TreeDefine(TYPE,line_no);
                            $$->addChild($1);
                            $$->addChild($3);
                        };

type                    :   standard_type   {$$=$1;}
		                |   record_type {$$=$1;}
		                |   array_type  {$$=$1;};

record_type             :   T_RECORD record_body T_END
                            {
                                $$=$2;
                            };
                        |   T_RECORD record_body 
                            {
                                $$=$2;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of end");

                            };

array_type              :   T_ARRAY T_LB periods T_RB T_OF type
                            {
                                $$=new TreeDefine(TK_ARRAY,line_no);
                                $$->addChild($3);
                                $$->addChild($6);
                                $$->setExpType(ET_ARRAY);
                            }
standard_type           :   T_INTEGER_TYPE
                            {
                                $$=new TreeDefine(SIMPLE_SYS,line_no);
                                $$->setExpType(INT);
                            }
		                |   T_REAL_TYPE
                            {
                                $$=new TreeDefine(SIMPLE_SYS,line_no);
                                $$->setExpType(REAL);
                            }
		                |   T_BOOLEAN_TYPE
                            {
                                $$=new TreeDefine(SIMPLE_SYS,line_no);
                                $$->setExpType(BOOL);
                            }
		                |   T_CHAR_TYPE
                            {
                                $$=new TreeDefine(SIMPLE_SYS,line_no);
                                $$->setExpType(CHAR);
                            };

record_body             :    var_declaration {$$=$1;};
                        |   {$$=NULL;}

periods                 :   periods T_COMMA period
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                              $$=$3;
                            }
                        |   periods period
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                              $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of comma");

                            }
		                |   period  {$$=$1;};

period                  :   const_variable T_DOTDOT const_variable
                            {
                                $$=new TreeDefine(TK_SIMPLE_LIMIT,line_no);
                                $$->addChild($1);
                                $$->addChild($3);
                                $$->setExpType(ET_SIMPLE_LIMIT);
                            };

var_declarations        :   {$$=NULL;}
		                |   T_VAR var_declaration T_SEMI  {$$=$2;};

var_declaration         :   var_declaration T_SEMI field_decl
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                                $$=$3;
                            }
                        |   var_declaration field_decl
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;

                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            }
		                |   field_decl  {$$=$1;};

field_decl              :   identifier_list T_COLON type
                            {
                                $$=new TreeDefine(DK_VAR,line_no);
                                $$->addChild($1);
                                $$->addChild($3);
                            };

subprogram_declarations :   {$$=NULL;}
		                |   subprogram_declarations subprogram_declaration T_SEMI
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            };
                        |   subprogram_declarations subprogram_declaration 
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };
subprogram_declaration  :   subprogram_head program_body
                            {
                                $$=new TreeDefine(PROGRAM,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                            };

subprogram_head         :   function_head
                            {
                                $$=$1;
                            }
		                |   procedure_head   {$$=$1;};

function_head           :   T_FUNCTION T_ID formal_parameter T_COLON standard_type T_SEMI
                            {
                                $$=new TreeDefine(FUNCTIONHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($3);
                                $$->addChild($5);
                            };
                        |   T_FUNCTION T_ID formal_parameter T_COLON standard_type
                            {
                                $$=new TreeDefine(FUNCTIONHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($3);
                                $$->addChild($5);
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };

procedure_head          :   T_PROCEDURE T_ID formal_parameter T_SEMI 
                            {
                                $$=new TreeDefine(PROCEDUREHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($3);
                            };
                        |   T_PROCEDURE T_ID formal_parameter 
                            {
                                $$=new TreeDefine(PROCEDUREHEAD,line_no);
                                $$->setAttribute($2);
                                $$->addChild($3);
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            };
formal_parameter        :   {$$=NULL;}
		                |   T_LP parameter_lists T_RP   {$$=$2;};
                        |   parameter_lists T_RP   
                            {
                                $$=$1;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of left parentthesis");
                            }
                        |   T_LP parameter_lists 
                            {
                                $$=$2;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of right parentthesis");

                            }
parameter_lists         :   parameter_lists T_SEMI parameter_list
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                                $$=$3;
                            }
		                |   parameter_list  {$$=$1;};
                        |   parameter_lists parameter_list
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");
                            }

parameter_list          :   var_parameter   {$$=$1;}
		                |   value_parameter {$$=$1;};

var_parameter           :   T_VAR value_parameter   
                            {
                                $$=new TreeDefine(VAR_PARA,line_no);
                                $$->addChild($2);
                            };

value_parameter         :   identifier_list T_COLON standard_type
                            {
                                $$=new TreeDefine(VAL_PARA,line_no);
                                $$->addChild($1);
                                $$->addChild($3);
                            };
                        |   identifier_list standard_type
                            {
                                $$=new TreeDefine(VAL_PARA,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of colon");

                            };

compound_statement      :   T_BEGIN statement_list T_END {$$=$2;};
                   

statement_list          :   {$$=NULL;}
                        |   statement_list T_SEMI statement 
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($3);
                                    $$=$1;
                                }
                                else
                                    $$=$3;
                            }
                        |   statement {$$=$1;};

statement               :   assign_statement {$$=$1;}
                        |   call_procedure_statement {$$=$1;}
                        |   compound_statement  {$$=$1;}
                        |   if_statement    {$$=$1;}
                        |   case_statement  {$$=$1;}
                        |   while_statement {$$=$1;}
                        |   repeat_statement {$$=$1;}
                        |   for_statement {$$=$1;}
                        |   {$$=NULL;};

assign_statement        :   variable T_ASSIGN expression
                            {
                                $$=new TreeDefine(ASSIGN,line_no);
                                $$->addChild($1);
                                $$->addChild($3);
                                $$->setAttribute(DK_VAR,4);
                            };
variable                :   ID id_varparts
                            {
                                $$=new TreeDefine(DK_VAR,line_no);
                                $$->addChild($1);
                                ($$->getChildren().at(0))->addChild($2);
                            };
id_varparts             :   id_varparts id_varpart
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($2);
                                    $$=$1;
                                }
                                else
                                    $$=$2;
                            }
                        |   {$$=NULL;}
                        |   id_varpart  {$$=$1;};

id_varpart              :   T_LB expression_list T_RB
                            {
                                $$=new TreeDefine(TK_ARRAY,line_no);
                                $$->addChild($2);
                                $$->setAttribute(TK_ARRAY,4);
                            }
                        |   T_DOT ID
                            {
                                $$=new TreeDefine(TK_RECORD,line_no);
                                $$->addChild($2);
                                $$->setAttribute(TK_RECORD,4);
                            };

else_part               :   T_ELSE statement    {$$=$2;}
                        |   {$$=NULL;};

case_body               :   branch_list {$$=$1;}
                        |   {$$=NULL;};

branch_list             :   branch_list T_SEMI branch
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                                $$=$3;
                            }
                        |   branch_list branch
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of semicolon");

                            }
                        |   branch{$$=$1;};

branch                  :   const_list T_COLON statement
                            {
                                $$=new TreeDefine(EK_CASE,line_no);
                                $$->addChild($1);
                                $$->addChild($3);
                            };
                        |   const_list statement
                            {
                                $$=new TreeDefine(EK_CASE,line_no);
                                $$->addChild($1);
                                $$->addChild($2);
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of colon");

                            };

const_list              :   const_list T_COMMA const_variable
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($3);
                                $$=$1;
                            }
                            else
                                $$=$3;
                            }
                        |   const_list const_variable
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                while(t->getSibling()!=NULL)
                                  t=t->getSibling();
                                t->setSibling($2);
                                $$=$1;
                            }
                            else
                                $$=$2;
                            errMsg.push_back("error at line " + to_string(line_no) + ", lack of comma");

                            }
                        |   const_variable{$$=$1;};

call_procedure_statement:   ID
                            {
                                $$=new TreeDefine(PROC_ID,line_no);
                                $$->setAttribute($1->getAttribute());
                            }
                        |   ID T_LP expression_list T_RP
                            {
                                $$=new TreeDefine(PROC_ID,line_no);
                                $$->setAttribute($1->getAttribute());
                                $$->addChild($3);
                            }
                        |   T_READ T_LP expression_list T_RP
                            {
                                $$=new TreeDefine(PROC_SYS,line_no);
                                $$->setAttribute(READ,4);
                                $$->addChild($3);
                            }
                        |   T_WRITE T_LP expression_list T_RP
                            {   
                                $$=new TreeDefine(PROC_SYS,line_no);
                                $$->setAttribute(WRITE,4);
                                $$->addChild($3);
                            };

expression_list         :   expression_list T_COMMA expression
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($3);
                                    $$=$1;
                                }
                                else
                                    $$=$3;
                            }
                        |   expression_list expression
                            {
                                TreeNode t=$1;
                                if(t!=NULL){
                                    while(t->getSibling()!=NULL)
                                        t=t->getSibling();
                                    t->setSibling($2);
                                    $$=$1;
                                }
                                else
                                    $$=$2;
                                errMsg.push_back("error at line " + to_string(line_no) + ", lack of comma");

                            }
                        |   expression{$$=$1;};

if_statement            :   T_IF expression T_THEN statement else_part
                            {
                                $$=new TreeDefine(IF,line_no);
                                $$->addChild($2);
                                $$->addChild($4);
                                $$->addChild($5);
                            };

case_statement          :   T_CASE expression T_OF case_body T_END
                        {   $$=new TreeDefine(SK_CASE,line_no);
                            $$->addChild($2);
                            $$->addChild($4);
                        };
while_statement         :   T_WHILE expression T_DO statement
                            {
                                $$=new TreeDefine(WHILE,line_no);
                                $$->addChild($2);
                                $$->addChild($4);
                            };

repeat_statement        :   T_REPEAT statement_list T_UNTIL expression
                            {
                                $$=new TreeDefine(REPEAT,line_no);
                                $$->addChild($2);
                                $$->addChild($4);
                            };

for_statement           :   T_FOR ID T_ASSIGN expression T_TO expression T_DO statement
                            {
                                $$=new TreeDefine(FOR,line_no);
                                $$->addChild($2);
                                $$->addChild($4);
                                $$->addChild($6);
                                $$->addChild($8);
                                $$->setAttribute(TO,4);
                            }
                        |   T_FOR ID T_ASSIGN expression T_DOWNTO expression T_DO statement
                            {
                                $$=new TreeDefine(FOR,line_no);
                                $$->addChild($2);
                                $$->addChild($4);
                                $$->addChild($6);
                                $$->addChild($8);
                                $$->setAttribute(DOWNTO,4);
                        };
 
expression              :   simple_expression T_EQUAL simple_expression{$$=new TreeDefine($1,$3,EQUAL,line_no);}
                        |   simple_expression T_GT simple_expression{$$=new TreeDefine($1,$3,GT,line_no);}
                        |   simple_expression T_LT simple_expression{$$=new TreeDefine($1,$3,LT,line_no);}
                        |   simple_expression T_GE simple_expression{$$=new TreeDefine($1,$3,GE,line_no);}
                        |   simple_expression T_LE simple_expression{$$=new TreeDefine($1,$3,LE,line_no);}
                        |   simple_expression T_UNEQUAL simple_expression{$$=new TreeDefine($1,$3,UNEQUAL,line_no);}
                        |   simple_expression  {$$=$1;};

simple_expression       :   term{$$=$1;}
                        |   T_PLUS term{$$=$2;}
                        |   T_MINUS term{$$=new TreeDefine($2, NULL, MINUS, line_no);}
                        |   simple_expression T_PLUS term{$$=new TreeDefine($1,$3,PLUS,line_no);}
                        |   simple_expression T_MINUS term{$$=new TreeDefine($1,$3,MINUS,line_no);}
                        |   simple_expression T_OR term{$$=new TreeDefine($1,$3,OR,line_no);};

term                    :   term T_MUL factor{$$=new TreeDefine($1,$3,MUL,line_no);}
                        |   term T_DIV factor{$$=new TreeDefine($1,$3,DIV,line_no);}
                        |   term T_AND factor{$$=new TreeDefine($1,$3,AND,line_no);}
                        |   term T_MOD factor{$$=new TreeDefine($1,$3,MOD,line_no);}
                        |   factor{$$=$1;};

factor                  :   unsign_const_variable{$$=$1;}
                        |   variable{$$=$1;}
                        |   ID T_LP expression_list T_RP
                            {
                                $$=new TreeDefine(FUNC_ID,line_no);
                                $$->setAttribute($1->getAttribute());
                                $$->addChild($3);
                            }
                        |   T_LP expression T_RP
                            {
                                $$=$2;
                            }
                        |   T_NOT factor{$$=new TreeDefine($2,NULL,NOT,line_no);};

unsign_const_variable   :   T_CHAR
                            {
                                $$ = new TreeDefine(EK_CONST,line_no);
                                $$->setExpType(CHAR);
                                $$->setAttribute($1);
                            }
                        |   T_INT
                            {
                                $$ =new TreeDefine(EK_CONST,line_no);
                                $$->setExpType(INT);
                                $$->setAttribute($1);
                            }
                        |   T_REAL
                            {
                                $$ = new TreeDefine(EK_CONST,line_no);
                                $$->setExpType(REAL);
                                $$->setAttribute($1);
                            };
%%

void yyerror(const char *s)
{
	cerr<<s<<" | line:"<<line_no<<endl;					//out error information
}
